class BaseService {
  /**
   * @description 构造函数
   * @param {*} knex - knex实例
   */
  constructor(DB=Chan.knex) {
    this.knex = DB;
    this.DB = DB;
    this.model = ''; // 默认为空字符串
  }

  /**
   * @description 查询表所有记录，慎用
   * @param {Object} query - 包含查询参数的对象
   * @returns {Promise} 返回所有记录
   */
  all(query={}) {
    if(Object.keys(query).length === 0) {
      return this.DB(this.model).select();
    }
    return this.DB(this.model).where(query).select();
  }

 /**
 * @description 根据指定条件查询记录
 * @param {Object} options - 包含查询参数的对象
 * @param {string} options.id - 查询字段名，默认为 'id'
 * @param {*} options.value - 查询字段值，默认为 0
 * @param {Array} options.field - 需要返回的字段数组，默认为空（即选择所有字段）
 * @param {number} options.len - 期望获取的记录数量，默认为 1（如果为 1 则使用 `.first()`，否则使用 `.limit(len)`）
 * @returns {Promise} 返回匹配条件的记录或记录列表
 */
async findById({ query, field = [], len = 1 }) {
  let dataQuery = this.DB(this.model).where(query);

  // 字段筛选
  if (field.length > 0) {
    dataQuery = dataQuery.select(field);
  }

  // 根据len决定是获取单条记录还是多条记录
  if (len === 1) {
    dataQuery = dataQuery.first();
  } else if (len > 1) {
    dataQuery = dataQuery.limit(len);
  }
  let res = await dataQuery;
  //返回结果 undefined 则返回空数组或空对象
  return res  || (len === 1 ? {} : []);
}


/**
 * @description 创建新记录
 * @param {Object} data - 包含要插入的数据对象
 * @returns {Promise<boolean>} 返回操作是否成功
 */
async insert(data = {}) {
  if (Object.keys(data).length === 0) {
    return false;
  }
  const result = await this.DB(this.model).insert(data);
  return result?.length > 0 || !!result;
}

  /**
 * @description 插入多条记录
 * @param {Array} records - 包含要插入的数据对象数组 [{<key>:<value>}, {<key>:<value>}, ...]
 * @returns {Promise<Array|Number>} 返回插入后的记录或受影响行数，具体取决于数据库驱动
 */
  async insertMany(records=[]) {
    // 如果没有提供数据或者数据为空，则直接返回 false 或者抛出异常
    if (records.length === 0) {
      console.log('插入数据不能为空')
      return false;
    }
  
    // 执行插入操作并获取结果
    const result = await this.DB(this.model).insert(records);
  
    // 返回插入的结果
    return result;
  }
  
 /**
 * @description 根据指定条件删除记录
 * @param {Object} query - 包含查询条件的对象
 * @returns {Promise<boolean>} 返回操作是否成功（即是否有任何记录被删除）
 */
 async delete(query = {}) {
  if (Object.keys(query).length === 0) {
    return false;
  }
  const affectedRows = await this.DB(this.model).where(query).del();
  return affectedRows > 0;
}
/**
 * @description 根据指定条件更新记录
 * @param {Object} query - 查询条件
 * @param {number} params - 保存内容
 * @returns {Promise<boolean>} 返回操作是否成功
 */
async  update({query, params} = {}) {
    const result = await this.DB(this.model).where(query).update(params);
    return { affectedRows: result };
}


/**
 * @description 批量更新多条记录（基于事务保证原子性）
 * @param {Array<{query: Object, params: Object}>} updates - 更新操作数组，每个元素包含查询条件和更新内容
 * @returns {Promise<{ affectedRows: number[] }>} 返回每个操作影响的行数数组
 */
async updateMany(updates = []) {
  // 参数合法性校验
  if (!Array.isArray(updates)) {
      throw new Error('参数必须为数组格式');
  }

  // 获取事务对象
  const trx = await this.DB.transaction();
  
  try {
      const affectedRows = [];
      // 循环处理每个更新操作
      for (const { query, params } of updates) {
          // 执行单个更新操作，使用事务对象替换原有knex实例
          const result = await trx(this.model)
              .where(query)
              .update(params);
          affectedRows.push(result);
      }
      // 提交事务
      await trx.commit();
      // 返回影响行数数组（与入参顺序一致）
      return { affectedRows };
  } catch (err) {
      // 回滚事务
      await trx.rollback();
      // 错误向上抛出，由调用者处理
      throw err;
  }
}




 /**
 * 查找所有符合条件的记录，并提供分页信息。
 * @param {Object} options - 包含查询参数的对象
 * @param {number} options.current - 当前页码，默认第一页
 * @param {number} options.pageSize - 每页大小，默认10条记录
 * @param {Object} options.query - 查询条件
 * @param {Array} options.field - 需要返回的字段
 * @returns {Promise<Object>} 返回包含数据列表、总记录数、当前页、每页大小的对象
 */
 async query({current = 1, pageSize = 10, query = {},field = []}) {
  const offset = (current - 1) * pageSize;
  let countQuery = this.DB(this.model).count("* as total");
  let dataQuery = this.DB(this.model);
  // 应用查询条件
  if(Object.keys(query).length > 0){
    Object.entries(query).forEach(([key, value]) => {
      dataQuery = dataQuery.where(key, value);
      countQuery = countQuery.where(key,value);
    })
  }

  //字段筛选
  if(field.length > 0){
    dataQuery = dataQuery.select(field);
  }

  //并行执行获取总记录数和分页数据的查询
  const [totalResult, list] = await Promise.all([countQuery.first(), dataQuery.offset(offset).limit(pageSize)]);
  // 提取总记录数
  const total =  totalResult?.total || 0;

  return { list, total, current, pageSize };
}


 /**
 * @description 查询指定条件的记录数量
 * @param {Array} query - 数组形式的多个条件 [{<key>:<value>}, {<key>:<value>}, ...]
 * @returns {Promise<number>} 返回符合条件的记录数量
 */
  async count(query=[]) {
      let dataQuery = this.DB(this.model);
      if(query.length >0){
        query.forEach((condition) => {
            dataQuery = dataQuery.where(condition);
        });
      }
      const result = await dataQuery.count("* as total").first();
      return result.total || 0;
  }
  
}
export default BaseService;